﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Pipeline.Design;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Design;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

namespace Pestre.SqlServer.SSIS.DataFlowComponent
{
    /*
     * VirtualInputColumn is a contener used to keep information relative 
     * to a Virtual Column and its usage.
     * 
     * The data stored in this class are :
     *    - Input Column ID
     *    - Input Column Lineage ID
     *    - Input Column Name
     *    - Input Column Upstream Component Name
     *    - Input Column Index in Input Buffer
     *    - Input ID
     *    - Input Name        
     *    - Output Column Usage
     *    - Output Column ID
     *    - Output Column Lineage ID
     *    - Output Column Name
     *    - Column Data Type
     *    - Output Column Index in Output Buffer
     *    
     * When an Input Column is connected, all Input information will be stored.
     * If user want to redirect this column to the Output Buffer, then Output information will be stored.
     */
    public class VirtualInputColumn100
    {
        // Input properties
        private int    _InputColumn_ID;
        private int    _InputColumn_LineageID;
        private string _InputColumn_Name;
        private string _InputColumn_UpstreamComponentName;
        private int    _Input_ID;
        private string _Input_Name;

        // Output properties
        private bool   _OutputColumn_IsUsed;
        private int    _OutputColumn_ID;
        private int    _OutputColumn_LineageID;
        private string _OutputColumn_Name;

        // Data Type
        private int _DataType;
        private int _Length;
        private int _Precision;
        private int _Scale;
        private int _CodePage;

        // RunTime properties
        private int _InputBufferIndex;
        private int _OutputBufferIndex;

        /*
         * Instanciate VirtualInputColumn from a storable object.
         * The parameter sCustomProperty comes from a custom property.
         */
        public VirtualInputColumn100(String sCustomProperty)
        {
            string[] tProp = sCustomProperty.Split(':');
            _InputColumn_ID = Int32.Parse(tProp[0]);
            _InputColumn_LineageID = Int32.Parse(tProp[1]);
            _InputColumn_Name = tProp[2];
            _InputColumn_UpstreamComponentName = tProp[3];
            _Input_ID = Int32.Parse(tProp[4]);
            _Input_Name = tProp[5];

            _OutputColumn_IsUsed = Boolean.Parse(tProp[6]);
            _OutputColumn_ID = Int32.Parse(tProp[7]);
            _OutputColumn_LineageID = Int32.Parse(tProp[8]);
            _OutputColumn_Name = tProp[9];

            _DataType = Int32.Parse(tProp[10]);
            _Length = Int32.Parse(tProp[11]);
            _Precision = Int32.Parse(tProp[12]);
            _Scale = Int32.Parse(tProp[13]);
            _CodePage = Int32.Parse(tProp[14]);

            _InputBufferIndex = -1;
            _OutputBufferIndex = -1;
        }

        /*
         * Instantiate VirtualInputColumn from an Input and a VirtualColumn.
         * All Input information will be stored, but output will be set to "UnUsed".
         */
        public VirtualInputColumn100(IDTSInput100 input, IDTSVirtualInputColumn100 vCol)
        {
            _InputColumn_ID = vCol.ID;
            _InputColumn_LineageID = vCol.LineageID;
            _InputColumn_Name = vCol.Name;
            _InputColumn_UpstreamComponentName = vCol.UpstreamComponentName;
            _Input_ID = input.ID;
            _Input_Name = input.Name;

            _OutputColumn_IsUsed = false;
            _OutputColumn_ID = -1;
            _OutputColumn_LineageID = -1;
            _OutputColumn_Name = vCol.Name;

            _DataType = (int)vCol.DataType;
            _Length = vCol.Length;
            _Precision = vCol.Precision;
            _Scale = vCol.Scale;
            _CodePage = vCol.CodePage;

            _InputBufferIndex = -1;
            _OutputBufferIndex = -1;
        }

        /*
         * Store Output information and set Output to "Used".
         */
        public void AttachOutput(IDTSOutputColumn100 outCol)
        {
            _OutputColumn_IsUsed = true;
            _OutputColumn_ID = outCol.ID;
            _OutputColumn_LineageID = outCol.LineageID;
            _OutputColumn_Name = outCol.Name;
        }

        /*
         * Reload Input information from an Input and a VirtualColumn.
         * Output information is not modified.
         */
        public void ReInitializeInput(IDTSInput100 input, IDTSVirtualInputColumn100 vCol)
        {
            if (_InputColumn_LineageID != vCol.LineageID)
                return;
            _InputColumn_ID = vCol.ID;
            _InputColumn_Name = vCol.Name;
            _InputColumn_UpstreamComponentName = vCol.UpstreamComponentName;
            _Input_ID = input.ID;
            _Input_Name = input.Name;
        }

        /*
         * Reload Data Type information from a VirtualColumn.
         * Input and Output information are not modified.
         */
        public void ReInitializeDataType(IDTSVirtualInputColumn100 vCol)
        {
            if (_InputColumn_LineageID != vCol.LineageID)
                return;

            _DataType = (int)vCol.DataType;
            _Length = vCol.Length;
            _Precision = vCol.Precision;
            _Scale = vCol.Scale;
            _CodePage = vCol.CodePage;
        }

        /*
         * Return true if the parameter vCol has the same data type
         * of the current instance of VirtualInputColumn.
         * 
         * This method is used to detect change in metadata.
         */
        public bool IsSameDataType(IDTSVirtualInputColumn100 vCol)
        {
            bool bCompare = true;

            if (vCol == null)
                bCompare = false;
            else if (_DataType != (int)vCol.DataType)
                bCompare = false;
            else if (_Length != vCol.Length)
                bCompare = false;
            else if (_Precision != vCol.Precision)
                bCompare = false;
            else if (_Scale != vCol.Scale)
                bCompare = false;
            else if (_CodePage != vCol.CodePage)
                bCompare = false;
            return bCompare;
        }

        /*
         * Store Input Buffer Index
         */
        public void SetInputBufferIndex(int index)
        {
            _InputBufferIndex = index;
        }

        /*
         * Store Output Buffer Index
         */
        public void SetOutputBufferIndex(int index)
        {
            _OutputBufferIndex = index;
        }

        /*
         * Transform this instance of VirtualInputColumn in a storable format.
         * The returned string will be stored in a custom property.
         *    - Each attribut is converted to String
         *    - Attributs are separated with ':'
         *    - At the end of the string a ';' is added
         */
        public override String ToString()
        {
            string sProperty = "";
            sProperty += _InputColumn_ID.ToString() + ":";
            sProperty += _InputColumn_LineageID.ToString() + ":";
            sProperty += _InputColumn_Name + ":";
            sProperty += _InputColumn_UpstreamComponentName + ":";
            sProperty += _Input_ID.ToString() + ":";
            sProperty += _Input_Name.ToString() + ":";
            sProperty += _OutputColumn_IsUsed.ToString() + ":";
            sProperty += _OutputColumn_ID.ToString() + ":";
            sProperty += _OutputColumn_LineageID.ToString() + ":";
            sProperty += _OutputColumn_Name + ":";
            sProperty += _DataType.ToString() + ":";
            sProperty += _Length.ToString() + ":";
            sProperty += _Precision.ToString() + ":";
            sProperty += _Scale.ToString() + ":";
            sProperty += _CodePage.ToString() + ";";
            return sProperty;
        }

        /*
         * Get Input Column ID
         */
        public int InputColumn_ID 
        { 
            get { return _InputColumn_ID; } 
        }

        /*
         * Get Input Column Lineage ID
         */
        public int InputColumn_LineageID 
        { 
            get { return _InputColumn_LineageID; } 
        }

        /*
         * Get Input Column Name
         */
        public string InputColumn_Name 
        {
            get { return _InputColumn_Name; } 
        }

        /*
         * Get Input Column Upstream Component Name
         */
        public string InputColumn_UpstreamComponentName 
        { 
            get { return _InputColumn_UpstreamComponentName; } 
        }

        /*
         * Get Input ID
         */
        public int Input_ID 
        { 
            get { return _Input_ID; } 
        }

        /*
         * Get Input Name
         */
        public string Input_Name 
        { 
            get { return _Input_Name; } 
        }

        /* 
         * Get and Set Output Columns Usage
         */
        public bool OutputColumn_IsUsed 
        { 
            get { return _OutputColumn_IsUsed; }
            set { _OutputColumn_IsUsed = value;  }
        }

        /*
         * Get Output Column ID
         */
        public int OutputColumn_ID 
        { 
            get { return _OutputColumn_ID; } 
        }

        /* 
         * Get Output Column Lineage ID
         */
        public int OutputColumn_LineageID 
        {
            get { return _OutputColumn_LineageID; } 
        }

        /*
         * Get Output Column Name
         */
        public string OutputColumn_Name 
        { 
            get { return _OutputColumn_Name; }
            set { _OutputColumn_Name = value; }
        }

        /*
         * Get and Set InputBufferIndex
         */
        public int InputBufferIndex 
        { 
            get { return _InputBufferIndex; }
            set { _InputBufferIndex = value; }
        }

        /*
         * Get and Set OutputBufferIndex
         */
        public int OutputBufferIndex 
        { 
            get { return _OutputBufferIndex; }
            set { _OutputBufferIndex = value; }
        }

        /*
         * Get Data Type
         */
        public int DataType 
        { 
            get { return _DataType; } 
        }

        /*
         * Get Length
         */
        public int Length 
        { 
            get { return _Length; } 
        }

        /*
         * Get Precision
         */
        public int Precision 
        { 
            get { return _Precision; } 
        }

        /*
         * Get Scale
         */
        public int Scale 
        { 
            get { return _Scale; } 
        }

        /*
         * Get Code Page
         */
        public int CodePage 
        { 
            get { return _CodePage; } 
        }
    }
}